/*
 * ========THE SOLMIX PROJECT=====================================
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.gnu.org/licenses/ 
 * or see the FSF site: http://www.fsf.org. 
 */

package org.solmix.fmk.datasource;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.solmix.SLXConstants;
import org.solmix.fmk.pool.PoolManager;
import org.solmix.services.datasource.DSRequest;
import org.solmix.services.datasource.DataSource;
import org.solmix.services.datasource.DataSourceManagerService;
import org.solmix.services.exception.SLXException;
import org.solmix.services.pool.PoolService;

/**
 * IDataSourceManager service implements.
 * 
 * @version $Id$
 */
public class DataSourceManager implements DataSourceManagerService
{

   private static final List< DataSource > providers;

   public static PoolManager manager = new PoolManager( SLXConstants.MODULE_DS_NAME, new PoolableDataSourceFactory() );
   static
   {
      providers = new CopyOnWriteArrayList< DataSource >();
      // and the default datasource implementations.
         providers.add( new BasicDataSource() );
//         providers.add( new SQLDataSource() );
     
   }

   public DataSourceManager()
   {

   }

   /*   *//**
    * return singlon instance.
    * 
    * @return
    */
   /*
    * public static DataSourceManager getInstance() { if (dsManager == null) dsManager = new DataSourceManager(); return
    * dsManager; }
    */
   /**
    * {@inheritDoc}
    * 
    * @see org.solmix.services.datasource.DataSourceManagerService#free(org.solmix.services.datasource.DataSource)
    */
   @Override
   public void free( DataSource ds )
   {
      freeDataSource( ds );

   }

   /**
    * {@inheritDoc}
    * 
    * @see org.solmix.services.datasource.DataSourceManagerService#freeDataSource(org.solmix.services.datasource.DataSource)
    */
   public static void freeDataSource( DataSource ds )
   {
      if ( ds == null )
      {
         return;
      } else if(ds.getContext().isWaitForFree())
      {
         manager.returnObject( ds.getName(), ds );
         ds.getContext().setWaitForFree(false);
      }

   }


   /**
    * {@inheritDoc}
    * 
    * @throws Exception
    * @see org.solmix.services.datasource.DataSourceManagerService#get(java.lang.String)
    */
   @Override
   public DataSource get( String name ) throws SLXException
   {
      return getDataSource(name);
   }

   /**
    * {@inheritDoc}
    * 
    * @throws Exception
    * @see org.solmix.services.datasource.DataSourceManagerService#getDataSource(java.lang.String)
    */
   public static DataSource getDataSource( String name ) throws SLXException
   {
       DataSource _return= (DataSource) manager.borrowObject( name );
       //avoid one borrow more than one return.
       _return.getContext().setWaitForFree(true);
       return _return;
   }

   /**
    * {@inheritDoc}
    * 
    * @throws Exception
    * @see org.solmix.services.datasource.DataSourceManagerService#getUnpooledDataSource(java.lang.String)
    */
   @Override
   public DataSource getUnpooledDataSource( String name ) throws SLXException
   {

      return (DataSource) manager.borrowUnpooledObject( name );
   }


   @Override
   public PoolService getPoolService()
   {
     return  manager;

   }

   /**
    * {@inheritDoc}
    * 
    * @see org.solmix.services.datasource.DataSourceManagerService#getProviders()
    */
   @Override
   public List< DataSource > getProviders()
   {
      return providers;
   }
   public static List<DataSource> getDataSourceProviders(){
      return providers;
   }

   public void unregister( DataSource datasource )
   {
       synchronized(providers){
        providers.remove( datasource );
       }
   }

   public void register( DataSource datasource )
   {
      String serverType=datasource.getServerType();
      if(serverType==null)
         return;
      synchronized(providers){
      for(DataSource ds:providers){
        if(serverType.equalsIgnoreCase(ds.getServerType()))
           providers.remove(ds);
      }
      providers.add( datasource );
      }
   }

   /**
    * {@inheritDoc}
    * 
    * @see org.solmix.services.datasource.DataSourceManagerService#get(java.lang.String, org.solmix.services.datasource.DSRequest)
    */
   @Override
   public DataSource get(String name, DSRequest request) throws SLXException
   {
      return getDataSource(name,request);
   }
   public static DataSource getDataSource( String name, DSRequest request ) throws SLXException
   {
       DataSource _return= (DataSource) manager.borrowObject( name ,request);
       _return.getContext().setWaitForFree(true);
       return _return;
   }
  public void destroy(){
      if(manager!=null)
      manager.destroy();
  }

/**
 * {@inheritDoc}
 * 
 * @see org.solmix.services.datasource.DataSourceManagerService#restartPoolService()
 */
@Override
public void restartPoolService() {
  manager = new PoolManager( SLXConstants.MODULE_DS_NAME, new PoolableDataSourceFactory() );
    
}
}
